#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time   : 2021/7/25 11:54
# @Author : cjw
from datetime import timedelta

from fastapi import APIRouter, Body, Depends, HTTPException, status, BackgroundTasks
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session

from app import crud
from app.api.utils.db import get_db
from app.api.utils.security import get_current_user
from app.core.config import settings
from app.core.jwt import create_access_token
from app.core.security import get_password_hash
from app.models.user import User as DBUser
from app.schemas.msg import Msg
from app.schemas.token import Token
from app.schemas.user import User
from app.utils.mail import send_reset_password_email
from app.core.jwt import (
    generate_password_reset_token,
    verify_password_reset_token
)

router = APIRouter()


@router.post('/login/access-token', response_model=Token, summary='获取token令牌')
def login_access_token(
        db: Session = Depends(get_db), form_data: OAuth2PasswordRequestForm = Depends()
):
    """
    通过登录用户名和密码，获取请求的访问令牌
    - **db**: 数据库连接
    - **form_data**: 提交的表单，包含用户名和密码
    """
    user = crud.user.authenticate(
        db, email=form_data.username, password=form_data.password
    )
    if not user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail='电子邮件或密码不正确',
            headers={"WWW-Authenticate": "Bearer"}
        )
    elif not crud.user.is_active(user):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail='非活跃用户')
    access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
    return {
        'access_token': create_access_token(
            data={'user_id': user.id}, expires_delta=access_token_expires
        ),
        'token_type': 'bearer'
    }


@router.post('/login/test-token', response_model=User, summary='验证token令牌')
def test_token(current_user: DBUser = Depends(get_current_user)):
    """
    测试token令牌
    - **current_user**: 当前用户
    """
    return current_user


@router.post('/password-recovery/{email}', response_model=Msg, summary='恢复密码')
def recover_password(email: str, bts: BackgroundTasks, db: Session = Depends(get_db)):
    """
    恢复密码
    - **email**: 需要恢复密码的用户邮箱
    """
    user = crud.user.get_by_email(db, email=email)

    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail='用户邮箱不存在'
        )
    password_reset_token = generate_password_reset_token(email=email)
    # 后台任务发送邮件
    bts.add_task(send_reset_password_email, '18367157420@163.com', email, password_reset_token)
    return {'msg': '已发送密码恢复电子邮件'}


@router.post('/reset-password/', response_model=Msg, summary='重置密码')
def reset_password(
        token: str = Body(...), new_password: str = Body(...), db: Session = Depends(get_db)
):
    """
    重置密码
    - **token**: 重置令牌
    - **new_password**: 新密码
    """
    email = verify_password_reset_token(token)
    if not email:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail='无效的令牌'
        )
    user = crud.user.get_by_email(db, email=email)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail='用户邮箱不存在'
        )
    hashed_password = get_password_hash(new_password)
    user.hashed_password = hashed_password
    db.add(user)
    db.commit()
    return {'msg': '密码更新成功'}
